#include "login_check_in_command.h"
#include "service/backend_service.h"
#include "../database/database_manager.h"
#include "command_executor.h"
#include <QDebug>
#include <QUrl>
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QStandardPaths>
#include <QDir>
#include <QFileInfo>
#include <QSettings>

LoginCheckinCommand::LoginCheckinCommand(QObject *parent)
    : BaseCommand(parent)
{
}

LoginCheckinCommand::~LoginCheckinCommand()
{
}

void LoginCheckinCommand::setNetworkAccessManager(QNetworkAccessManager *networkManager)
{
    // 如果之前已经设置了 networkManager，先断开旧的连接
    if (m_networkManager) {
        disconnect(m_networkManager, &QNetworkAccessManager::finished,
                   this, &LoginCheckinCommand::handleLoginResponse);
    }
    
    BaseCommand::setNetworkAccessManager(networkManager);
    
    // 连接网络请求完成信号
    if (m_networkManager) {
        connect(m_networkManager, &QNetworkAccessManager::finished,
                this, &LoginCheckinCommand::handleLoginResponse);
    }
}

bool LoginCheckinCommand::execute(const QString &username, const QString &password, const QString &checkcode)
{
    if (!isValid()) {
        qDebug() << "LoginCheckinCommand: BackendService 或 QNetworkAccessManager 未设置";
        emit loginResult(-1, "BackendService 或 QNetworkAccessManager 未设置", QStringList());
        return false;
    }
    
    // 保存当前登录用户名
    m_currentUsername = username;
    
    // 获取 baseUrl
    QString baseUrl = getBaseUrl();
    
    // 构建请求URL
    QString url = buildRequestUrl(baseUrl);
    
    // 对密码进行base64编码
    QString encodedPassword = QString::fromUtf8(password.toUtf8().toBase64());
    
    // 将最后2位移到最前面
    if (encodedPassword.length() > 2) {
        QString lp = encodedPassword.left(2);
        QString rp = encodedPassword.right(encodedPassword.length() - 2);
        encodedPassword = rp + lp;
    }
    
    qDebug() << "LoginCheckinCommand: 原始密码:" << password;
    qDebug() << "LoginCheckinCommand: Base64编码后:" << QString::fromUtf8(password.toUtf8().toBase64());
    qDebug() << "LoginCheckinCommand: 最后2位移到前面后:" << encodedPassword;
    
    // 构建请求体
    QJsonObject requestBody;
    requestBody["username"] = username;
    requestBody["password"] = encodedPassword;
    requestBody["checkcode"] = checkcode;
    
    QJsonDocument doc(requestBody);
    QByteArray data = doc.toJson();
    
    // 创建网络请求
    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setHeader(QNetworkRequest::ContentLengthHeader, data.size());
    
    qDebug() << "LoginCheckinCommand: 发送登录请求到:" << url;
    qDebug() << "LoginCheckinCommand: 请求体:" << data;
    
    // 发送POST请求
    QNetworkReply *reply = m_networkManager->post(request, data);
    if (!reply) {
        qDebug() << "LoginCheckinCommand: 创建网络请求失败";
        emit loginResult(-1, "创建网络请求失败", QStringList());
        return false;
    }
    
    qDebug() << "LoginCheckinCommand: 发送请求，reply对象:" << reply;
    
    // 设置用户数据，用于识别请求类型
    reply->setProperty("requestType", "login");
    
    return true;
}

void LoginCheckinCommand::handleLoginResponse(QNetworkReply *reply)
{
    // 检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "LoginCheckinCommand: 对象已被销毁，忽略响应";
        if (reply) {
            reply->deleteLater();
        }
        return;
    }
    
    if (!reply) {
        qDebug() << "LoginCheckinCommand: 登录响应为空";
        if (isValid()) {
            emit loginResult(-1, "登录响应为空", QStringList());
        }
        return;
    }
    
    QString requestType = reply->property("requestType").toString();
    if (requestType != "login") {
        // 不是登录请求，忽略
        reply->deleteLater();
        return;
    }
    
    // 打印reply详细信息
    qDebug() << "LoginCheckinCommand: 收到服务器响应，reply对象:" << reply;
    qDebug() << "LoginCheckinCommand: 响应状态码:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug() << "LoginCheckinCommand: 响应头信息:" << reply->rawHeaderPairs();
    
    // 检查网络错误
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "LoginCheckinCommand: 网络请求错误:" << reply->errorString();
        if (isValid()) {
            emit loginResult(-1, "网络请求失败: " + reply->errorString(), QStringList());
        }
        reply->deleteLater();
        return;
    }
    
    // 提取并保存token
    QByteArray setCookieHeader = reply->rawHeader("set-cookie");
    if (!setCookieHeader.isEmpty()) {
        QString setCookieStr = QString::fromUtf8(setCookieHeader);
        qDebug() << "LoginCheckinCommand: 收到set-cookie头:" << setCookieStr;
        
        // 解析checkInToken
        if (setCookieStr.contains("checkInToken=")) {
            int startPos = setCookieStr.indexOf("checkInToken=") + 13; // "checkInToken="的长度
            int endPos = setCookieStr.indexOf(";", startPos);
            if (endPos == -1) {
                endPos = setCookieStr.length();
            }
            QString checkInToken = setCookieStr.mid(startPos, endPos - startPos);
            qDebug() << "LoginCheckinCommand: 提取到checkInToken:" << checkInToken;
            
            // 保存token（通过 BackendService 的公共方法）
            if (m_backendService) {
                // 需要添加公共方法 saveCheckInToken
                // 暂时直接实现保存逻辑
                QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
                if (!homePath.isEmpty()) {
                    QString settingsPath = QDir(homePath).filePath(".myapps/setting.ini");
                    QDir dir;
                    QString settingsDir = QFileInfo(settingsPath).absolutePath();
                    if (!dir.exists(settingsDir)) {
                        dir.mkpath(settingsDir);
                    }
                    QSettings settings(settingsPath, QSettings::IniFormat);
                    settings.setValue("Auth/CheckInToken", checkInToken);
                    qDebug() << "LoginCheckinCommand: Token已保存到:" << settingsPath;
                }
            }
        }
    }
    
    // 读取响应数据
    QByteArray responseData = reply->readAll();
    qDebug() << "LoginCheckinCommand: 登录响应数据包:" << responseData;
    qDebug() << "LoginCheckinCommand: 响应数据长度:" << responseData.size() << "字节";
    
    // 解析JSON响应
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(responseData, &parseError);
    
    // 再次检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "LoginCheckinCommand: 对象已被销毁，忽略响应解析";
        reply->deleteLater();
        return;
    }
    
    if (parseError.error != QJsonParseError::NoError) {
        qDebug() << "LoginCheckinCommand: JSON解析错误:" << parseError.errorString();
        if (isValid()) {
            emit loginResult(-2, "响应数据格式错误", QStringList());
        }
        reply->deleteLater();
        return;
    }
    
    if (!doc.isObject()) {
        qDebug() << "LoginCheckinCommand: 响应数据不是有效的JSON对象";
        if (isValid()) {
            emit loginResult(-3, "响应数据格式错误", QStringList());
        }
        reply->deleteLater();
        return;
    }
    
    QJsonObject response = doc.object();
    parseLoginResponse(response, m_currentUsername);
    
    reply->deleteLater();
}

void LoginCheckinCommand::parseLoginResponse(const QJsonObject &response, const QString &username)
{
    // 检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "LoginCheckinCommand: 对象已被销毁，忽略响应解析";
        return;
    }
    
    // 解析响应字段
    int resultCode = response["resultCode"].toInt();
    QString message = response["msg"].toString();
    QStringList domains;
    
    // 解析domains数组
    if (response.contains("domains") && response["domains"].isArray()) {
        QJsonArray domainsArray = response["domains"].toArray();
        
        // 保存完整的domains信息（通过 BackendService 的公共方法）
        if (m_backendService) {
            m_backendService->saveDomains(domainsArray);
            qDebug() << "LoginCheckinCommand: 已通过 BackendService 保存 Domains，数量:" << domainsArray.size();
        }
        
        // 同时构建简化的domains列表用于信号传递
        for (const QJsonValue &value : domainsArray) {
            if (value.isObject()) {
                QJsonObject domain = value.toObject();
                QString domainId = domain["id"].toString();
                QString domainName = domain["name"].toString();
                domains << QString("%1:%2").arg(domainId, domainName);
            }
        }
    }
    
    qDebug() << "LoginCheckinCommand: 登录结果 - 代码:" << resultCode << "消息:" << message << "域名数量:" << domains.size();
    
    // 如果登录成功，创建用户工作目录
    if (resultCode == 0) {
        // 设置当前用户ID到数据库管理器
        if (m_databaseManager) {
            m_databaseManager->setCurrentUserId(username);
            qDebug() << "LoginCheckinCommand: 已设置当前用户ID到数据库管理器:" << username;
        }
        
        // 创建用户工作目录
        QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
        if (!homePath.isEmpty()) {
            QString workDirectory = QDir(homePath).filePath(".myapps/" + username);
            QDir dir;
            if (!dir.exists(workDirectory)) {
                if (dir.mkpath(workDirectory)) {
                    qDebug() << "LoginCheckinCommand: 成功创建用户工作目录:" << workDirectory;
                    emit userWorkDirectoryCreated(username, workDirectory);
                } else {
                    qDebug() << "LoginCheckinCommand: 创建用户工作目录失败:" << workDirectory;
                }
            } else {
                qDebug() << "LoginCheckinCommand: 用户工作目录已存在:" << workDirectory;
                emit userWorkDirectoryCreated(username, workDirectory);
            }
        }
    }
    
    // 最后一次检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "LoginCheckinCommand: 对象已被销毁，无法发送完成信号";
        return;
    }
    
    // 如果登录成功，获取accessToken
    if (resultCode == 0) {
        ensureAccessToken();
    }

    // 发送登录结果信号
    emit loginResult(resultCode, message, domains);
}

QString LoginCheckinCommand::buildRequestUrl(const QString &baseUrl)
{
    return baseUrl + "/signon/api/runtime/login/checkin";
}

